﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace _05_03控件命令绑定
{
	public class MyCommandParam : ICommand
	{
		

		private readonly Action<object> _execute;
		private readonly Func<object, bool> _canExecute;

		public MyCommandParam(Action<object> execute, Func<object, bool> canExecute = null)
		{
			_execute = execute ?? throw new ArgumentNullException(nameof(execute));
			_canExecute = canExecute;
		}

		public bool CanExecute(object? parameter)
		{
			return _canExecute == null || _canExecute(parameter);
		}

		public void Execute(object? parameter)
		{
			_execute(parameter);
		}

		//这段代码是用于处理命令的可执行状态改变的事件。在MVVM模式中，ICommand接口定义了一个CanExecuteChanged事件，用于通知命令的可执行状态已经发生改变。
		//在上述代码中，通过将CommandManager.RequerySuggested事件的处理程序添加到CanExecuteChanged事件中，可以在命令的可执行状态发生改变时触发该事件。
		//CommandManager.RequerySuggested事件是一个由WPF框架提供的特殊事件，它在以下情况下会被触发：
		//1当控件获得焦点时
		//2当控件失去焦点时
		//3当控件的Command属性或CommandParameter属性发生改变时
		//4当CommandManager.InvalidateRequerySuggested方法被调用时
		//通过在CanExecuteChanged事件中添加和移除CommandManager.RequerySuggested事件的处理程序，可以确保命令的可执行状态在需要重新评估时进行更新。
		//这样，在满足命令可执行条件的情况下，控件会自动启用或禁用相应的命令。
		public event EventHandler CanExecuteChanged
		{
			add { CommandManager.RequerySuggested += value; }
			remove { CommandManager.RequerySuggested -= value; }
		}


		

	}

	public class MyCommandNoParam:ICommand
	{
		//不带参数的
		private readonly Action _execute;
		private readonly Func<object, bool> _canExecute;

		public MyCommandNoParam(Action execute, Func<object, bool> canExecute = null)
		{
			_execute = execute ?? throw new ArgumentNullException(nameof(execute));
			_canExecute = canExecute;
		}

		public bool CanExecute(object parameter)
		{
			return _canExecute == null || _canExecute(parameter);
		}

		public void Execute(object? parameter)
		{
			//？是判断是否为空
			_execute?.Invoke();
		}

		//这段代码是用于处理命令的可执行状态改变的事件。在MVVM模式中，ICommand接口定义了一个CanExecuteChanged事件，用于通知命令的可执行状态已经发生改变。
		//在上述代码中，通过将CommandManager.RequerySuggested事件的处理程序添加到CanExecuteChanged事件中，可以在命令的可执行状态发生改变时触发该事件。
		//CommandManager.RequerySuggested事件是一个由WPF框架提供的特殊事件，它在以下情况下会被触发：
		//1当控件获得焦点时
		//2当控件失去焦点时
		//3当控件的Command属性或CommandParameter属性发生改变时
		//4当CommandManager.InvalidateRequerySuggested方法被调用时
		//通过在CanExecuteChanged事件中添加和移除CommandManager.RequerySuggested事件的处理程序，可以确保命令的可执行状态在需要重新评估时进行更新。
		//这样，在满足命令可执行条件的情况下，控件会自动启用或禁用相应的命令。
		public event EventHandler CanExecuteChanged
		{
			add { CommandManager.RequerySuggested += value; }
			remove { CommandManager.RequerySuggested -= value; }
		}
	}

	public class MyCommand : ICommand
	{
		private readonly Action<object> _executeParam;
		private readonly Action _executeNoParam;
		private readonly Func<object, bool> _canExecute;

		public MyCommand(Action<object> execute, Func<object, bool> canExecute = null)
		{
			_executeParam = execute ?? throw new ArgumentNullException(nameof(execute));
			_canExecute = canExecute;
		}
		public MyCommand(Action execute, Func<object, bool> canExecute = null)
		{
			_executeNoParam = execute ?? throw new ArgumentNullException(nameof(execute));
			_canExecute = canExecute;
		}

		public bool CanExecute(object? parameter)
		{
			return _canExecute == null || _canExecute(parameter);
		}

		public void Execute(object? parameter)
		{
			if(_executeParam!=null)
			{
				_executeParam(parameter);
			}
			else if(_executeNoParam!=null)
			{
				_executeNoParam.Invoke();
			}
		}

		//这段代码是用于处理命令的可执行状态改变的事件。在MVVM模式中，ICommand接口定义了一个CanExecuteChanged事件，用于通知命令的可执行状态已经发生改变。
		//在上述代码中，通过将CommandManager.RequerySuggested事件的处理程序添加到CanExecuteChanged事件中，可以在命令的可执行状态发生改变时触发该事件。
		//CommandManager.RequerySuggested事件是一个由WPF框架提供的特殊事件，它在以下情况下会被触发：
		//1当控件获得焦点时
		//2当控件失去焦点时
		//3当控件的Command属性或CommandParameter属性发生改变时
		//4当CommandManager.InvalidateRequerySuggested方法被调用时
		//通过在CanExecuteChanged事件中添加和移除CommandManager.RequerySuggested事件的处理程序，可以确保命令的可执行状态在需要重新评估时进行更新。
		//这样，在满足命令可执行条件的情况下，控件会自动启用或禁用相应的命令。
		public event EventHandler CanExecuteChanged
		{
            //在界面中，当账号密码没有值的时候是false的，canExecute是空的，但是输入值后canExecute是true,可以执行命令了
            add { CommandManager.RequerySuggested += value; }
			remove { CommandManager.RequerySuggested -= value; }
		}




	}
}
